#include "myglwidget.h"


//Constructeur
MyGLWidget::MyGLWidget(int framesPerSecond, QWidget *parent, char *name)
    : QGLWidget(parent)
{
    setWindowTitle(QString::fromUtf8(name));
    if(framesPerSecond == 0)
        t_Timer = NULL;
    else
    {
        int seconde = 1000; // 1 seconde = 1000 ms
        int timerInterval = seconde / framesPerSecond;
        t_Timer = new QTimer(this);
        connect(t_Timer, SIGNAL(timeout()), this, SLOT(timeOutSlot()));
        t_Timer->start( timerInterval );
    }

    hyper = new Hyperboloid();
    tore = new Tore(1.0, 4.0, 16, 16);
    sphere = new Sphere();
    angleRotation = 0.0;
    textureChargee = false;
}

//Fonction se produisant lors de l'appuie sur une touche
void MyGLWidget::keyPressEvent(QKeyEvent *keyEvent)
{
    switch(keyEvent->key())
    {
        case Qt::Key_Escape:
            close();
            break;
        case Qt::Key_F:
            glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
            updateGL();
            break;
        case Qt::Key_P:
            glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
            updateGL();
            break;
        case Qt::Key_W:
            glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
            updateGL();
            break;
    }
}

void MyGLWidget::chargerTexture()
{
    textureChargee = true;

    QImage qim_Texture;
    QImage qim_TempTexture;
    GLuint tex_id;

    qim_TempTexture.load("woodBox.bmp");
    qim_Texture = QGLWidget::convertToGLFormat( qim_TempTexture );
    glGenTextures( 1, &textureId );
    glBindTexture( GL_TEXTURE_2D, textureId );
    glTexImage2D( GL_TEXTURE_2D, 0, 3, qim_Texture.width(), qim_Texture.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, qim_Texture.bits() );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
}

//Fonction permettant d'initialiser la fenêtre opengl
void MyGLWidget::initializeGL()
{
    glShadeModel(GL_SMOOTH);
    glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    glEnable(GL_TEXTURE_2D);
}

//Fonction appelée lors du redimensionnement de la fenêtre
void MyGLWidget::resizeGL(int width, int height)
{
    if(height == 0)
        height = 1;
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0f, (GLfloat)width/(GLfloat)height, 0.1f, 100.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

//Fonction appelée pour dessiner notre scène
void MyGLWidget::paintGL()
{

    if(!textureChargee)
        chargerTexture();

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glTranslatef(-1.5f, 0.0f, -6.0f);


    glBegin(GL_QUADS);
        //devant
        glTexCoord2f(0.0, 0.0);
        glVertex3f(-1.0,-1.0,-1.0);
        glTexCoord2f(1.0, 0.0);
        glVertex3f(1.0,-1.0,-1.0);
        glTexCoord2f(1.0, 1.0);
        glVertex3f(1.0,1.0,-1.0);
        glTexCoord2f(0.0, 1.0);
        glVertex3f(-1.0,1.0,-1.0);

        //derriere
        glTexCoord2f(0.0, 0.0);
        glVertex3f(-1.0,-1.0,1.0);
        glTexCoord2f(1.0, 0.0);
        glVertex3f(1.0,-1.0,1.0);
        glTexCoord2f(1.0, 1.0);
        glVertex3f(1.0,1.0,1.0);
        glTexCoord2f(0.0, 1.0);
        glVertex3f(-1.0,1.0,1.0);

        //gauche
        glTexCoord2f(0.0, 0.0);
        glVertex3f(-1.0,-1.0,-1.0);
        glTexCoord2f(1.0, 0.0);
        glVertex3f(-1.0,1.0,-1.0);
        glTexCoord2f(1.0, 1.0);
        glVertex3f(-1.0,1.0,1.0);
        glTexCoord2f(0.0, 1.0);
        glVertex3f(-1.0,-1.0,1.0);

        //droite
        glTexCoord2f(0.0, 0.0);
        glVertex3f(1.0,-1.0,-1.0);
        glTexCoord2f(1.0, 0.0);
        glVertex3f(1.0,1.0,-1.0);
        glTexCoord2f(1.0, 1.0);
        glVertex3f(1.0,1.0,1.0);
        glTexCoord2f(0.0, 1.0);
        glVertex3f(1.0,-1.0,1.0);

        //dessus
        glTexCoord2f(0.0, 0.0);
        glVertex3f(-1.0,1.0,-1.0);
        glTexCoord2f(1.0, 0.0);
        glVertex3f(1.0,1.0,-1.0);
        glTexCoord2f(1.0, 1.0);
        glVertex3f(1.0,1.0,1.0);
        glTexCoord2f(0.0, 1.0);
        glVertex3f(-1.0,1.0,1.0);

        //dessous
        glTexCoord2f(0.0, 0.0);
        glVertex3f(-1.0,-1.0,-1.0);
        glTexCoord2f(1.0, 0.0);
        glVertex3f(1.0,-1.0,-1.0);
        glTexCoord2f(1.0, 1.0);
        glVertex3f(1.0,-1.0,1.0);
        glTexCoord2f(0.0, 1.0);
        glVertex3f(-1.0,-1.0,1.0);
    glEnd();


    glTranslatef(-1.5f, 0.0f, -6.0f);
    glRotatef(angleRotation, 0.0, 1.0, 0.0);
    glRotatef(45, 1.0, 1.0, 0.0);
    glTranslatef(15.0, -3.0, -6.0);
    tore->dessiner();
}

//Fonction appelée lors du rafraichissement
void MyGLWidget::timeOutSlot()
{
    updateGL();
}

//Slot à affecter à un signal pour recevoir un changement d'angle
void MyGLWidget::setAngle(int angle)
{
    if(angle > 360)
    {
        angle %= 360;
    }

    angleRotation = angle;
}
